package firstcontent.reference;

import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;

/**
 * @Author: fxy
 * @Date: 2022/02/25/9:42
 * @Description:
 */
public class PhantomReferenceTest {
    public static PhantomReferenceTest obj;
    static ReferenceQueue<PhantomReferenceTest> phantomQueue = null;

    public static class CheckRefQueue extends Thread{
        @Override
        public void run(){
            while(true){
                if(phantomQueue!=null){
                    PhantomReference<PhantomReferenceTest> objt = null;
                    try {
                        objt = (PhantomReference<PhantomReferenceTest>) phantomQueue.remove();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    if(objt!=null){
                        System.out.println("追踪垃圾回收过程：PhantomReferenceTest实例被回收了");
                    }
                }
            }
        }
    }

    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        System.out.println("调用当前类的finalize()方法");
        obj = this;
    }

    public static void main(String[] args) {
        Thread t = new CheckRefQueue();
        //设置为守护线程，当程序中没有非守护线程时，守护线程也就结束了
        t.setDaemon(true);
        t.start();

        phantomQueue = new ReferenceQueue<>();
        obj = new PhantomReferenceTest();
        PhantomReference<PhantomReferenceTest> phantomRef = new PhantomReference<>(obj,phantomQueue);
        /**
         * 不可获取虚引用中的对象
         */
        System.out.println(phantomRef.get());
        obj = null;
        System.gc();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        if(obj  == null){
            System.out.println("obj is null");
        }else {
            System.out.println("obj 可用");
        }
        System.out.println("第二次gc");
        obj = null;
        System.gc();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        if(obj  == null){
            System.out.println("obj is null");
        }else {
            System.out.println("obj 可用");
        }

    }
}
